<!-- @format -->

<template>
  <div class="article-detail">
    <div v-if="loading" class="loading-container">
      <base-loading message="内容加载中..." />
    </div>
    <div v-else-if="error" class="error-container">
      <wd-notice-bar :text="error" type="danger" />
    </div>
    <div v-else>
      <div class="article-header">
        <h1 class="article-title">{{ title }}</h1>
        <view @click="onRefresh" class="refresh-x">
          <view
            class="icon-x"
            :style="iconStyl"
            :class="{ rotate: refreshing }"
          >
            <wd-icon name="refresh" />
          </view>
          更新
        </view>
      </div>
      <div class="markdown-content">
        <mp-html
          :markdown="true"
          :content="htmlContent"
          :tag-style="tagStyle"
          :container-style="containerStyle"
          :domain="domain"
          @linktap="handleLinkTap"
          @imgtap="handleImageTap"
        />
      </div>
    </div>
    <wd-toast />
  </div>
</template>

<script lang="ts" setup>
import { onLoad } from '@dcloudio/uni-app'
import mpHtml from 'mp-html/dist/uni-app/components/mp-html/mp-html'
import { computed, ref } from 'vue'
import { useToast } from 'wot-design-uni'
import BaseLoading from '../../components/BaseLoading.vue'
import { useCache } from '../../composables/useCache'
import { GiteeService } from '../../services/giteeService'
import { extractTitleFromPath, parseGiteeUrl } from '../../utils/commonUtils'
import { md5 } from '../../utils/md5Utils'

const toast = useToast()

const loading = ref(true)
const refreshing = ref(false)
const error = ref<string | null>(null)
const content = ref('')
const title = ref('')
const domain = ref('')
const giteeService = new GiteeService()
const params = ref<any>(null)

let refreshTime = 0
const iconStyl = ref({})

const tagStyle = {
  h1: 'font-size: 28px; font-weight: bold; margin: 1.5em 0; color: #2c405a;',
  h2: 'font-size: 24px; font-weight: bold; margin: 1.2em 0; color: #2c405a;',
  h3: 'font-size: 20px; font-weight: bold; margin: 1em 0; color: #2c405a;',
  p: 'margin: 0.8em 0; line-height: 1.6; color: #3f536e;',
  a: 'color: #007bff; text-decoration: none; transition: color 0.3s;',
  'a:hover': 'color: #0056b3; text-decoration: underline;',
  img: 'max-width: 100%; height: auto; border-radius: 8px;',
  blockquote:
    'border-left: 4px solid #eaecef; padding-left: 16px; color: #6c757d; margin: 1em 0; background-color: #f9f9f9; border-radius: 4px; padding: 10px;',
  ul: 'list-style-type: disc; padding-left: 20px; margin: 0.5em 0;',
  ol: 'list-style-type: decimal; padding-left: 20px; margin: 0.5em 0;',
}

const containerStyle = 'background-color: #fff;'

const htmlContent = computed(() => {
  return content.value
})

const handleLinkTap = (e: any) => {
  const href = e.href
  if (href.startsWith('http')) {
    // 使用 WebView 打开链接
    uni.navigateTo({
      url: `/pages/webview/browser?url=${encodeURIComponent(href)}`,
    })
  } else {
    let p = href
    const { owner, repo, path } = params.value
    if (href.startsWith('.')) {
      let l = path.split('/')
      l[l.length - 1] = href.replace('./', '')
      p = l.join('/')
    }

    const query = `owner=${owner}&repo=${repo}&path=${p}`
    uni.navigateTo({
      url: `/pages/article/detail?${query}`,
    })
  }
}

const handleImageTap = (e: any) => {
  const current = e.src
  uni.previewImage({
    current,
    urls: [current],
  })
}

const loadArticle = async (refresh = false) => {
  const { owner, repo, path, url } = params.value
  if (!url && (!owner || !repo || !path)) {
    error.value = '参数错误'
    loading.value = false
    return
  }

  const key = url ? url : `article-${owner}-${repo}-${path}`
  const hashKey = md5(key)
  const cache = useCache<string>(hashKey, -1) // 5分钟缓存

  if (!refresh) {
    // 尝试从缓存中获取文章内容
    const cachedContent = cache.getItem()
    if (cachedContent) {
      content.value = cachedContent
      title.value = extractTitleFromPath(url || path)
      loading.value = false
      return
    }
  }

  try {
    let articleContent = { content: '' }
    if (url) {
      articleContent = await giteeService.getFileContentByUrl(url)
    } else {
      articleContent = await giteeService.getFileContent(owner, repo, path)
    }
    content.value = articleContent.content
    title.value = extractTitleFromPath(url || path)
    // 将文章内容缓存到本地
    cache.setItem(articleContent.content)
  } catch (err) {
    error.value = '加载文章失败，请稍后重试'
    console.error('加载文章失败:', err)
  } finally {
    loading.value = false
    // 为了优化每次刷新结束后图标旋转动效更流畅，我们在这里设置一个定时器，确保图标旋转动效在刷新完成后立即停止
    refreshFinish()
  }
}

const onRefresh = async () => {
  refreshing.value = true
  refreshTime = Date.now()
  await loadArticle(true)
  toast.show('更新成功')
}

const refreshFinish = () => {
  if (!refreshing.value) return
  const current = (((Date.now() - refreshTime) % 1000) * 360) / 1000
  iconStyl.value = { transform: `rotate(${current}deg)` }
  refreshing.value = false
  setTimeout(() => {
    iconStyl.value = { transform: 'rotate(360deg)' }
  }, 60)
}

onLoad((option) => {
  if (option?.url) {
    const { owner, repo, path } = parseGiteeUrl(option.url)
    option.owner = owner
    option.repo = repo
    option.path = path
  }
  params.value = option

  loadArticle()
})
</script>

<style scoped>
.language-javascript {
  color: red;
}

.article-detail {
  min-height: 100vh;
  background-color: #f8f9fa;
}

.loading-container,
.error-container {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 200px;
}

.article-header {
  padding: 20px;
  background-color: #fff;
  margin-bottom: 12px;
  border-bottom: 1px solid #eaecef;
}

.article-title {
  font-size: 24px;
  font-weight: 600;
  color: #2c3e50;
}

.refresh-x {
  font-size: 28rpx;
  margin-top: 8rpx;
}

.markdown-content {
  max-width: 900px;
  margin: 0 auto;
  padding: 16px;
  background-color: #fff;
}

.refresh-btn {
  padding: 10px 20px;
  border: none;
  border-radius: 20px;
  background-color: #007bff;
  color: white;
  cursor: pointer;
}

.wd-icon {
  font-size: 24px;
}

.icon-x {
  display: inline-block;
  transition: transform 0.4s linear;
  transform: rotate(0deg);
}

.rotate {
  animation: rotate 1s linear infinite;
}

@keyframes rotate {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}
</style>
